import { Worker, WorkerOptions } from "worker_threads";
import { fork } from "child_process";
import { getWorkerPath } from "./fs";
import { ENV_IS_DEV } from "../constants/common";

export * from "./array";
export * from "./date";
export * from "./fs";
export * from "./number";
export * from "./os";


/**
 * 单例 promise版
 * @param p
 * @param getKey 从参数里取一个直用于缓存该请求是否合并
 * @example
 * const getProjectSingle =  singlePromise(getProject, (projectId) => projectId)
 * /// 3合一
 * getProjectSingle('1');
 * getProjectSingle('1');
 * getProjectSingle('1');
 * /// 参数不一致，会发出
 * getProjectSingle('2');
 */
export function singlePromise<T extends (...arg: any[]) => Promise<any>>(p: T, getKey?: (...arg: Parameters<T>) => string | number) {
  const cache: Record<string, Promise<any> | undefined> = {}
  return (...arg: Parameters<T>): ReturnType<T> => {
    const key = getKey ? getKey(...arg) : 'default'
    if (cache[key]) {
      return cache[key] as ReturnType<T>
    }
    cache[key] = p(...arg).finally(() => {
      delete cache[key]
    })
    return cache[key] as ReturnType<T>
  }
}
export function runWorker<T extends (arg: Record<string, any>) => any>(path: string, args: Parameters<T>[0], options?: WorkerOptions){
  return new Promise<ReturnType<T>>((resolve, reject) => {
      if (ENV_IS_DEV) {
        const worker = fork(getWorkerPath(path));
        worker.on('message', (msg) => {
          resolve(msg)
          worker.kill()
        });
        worker.on('error', (err) => {
          reject(err)
        });
        if (options && options.workerData) {
          worker.send({type: 'workerData', workerData: options.workerData})
        }
        worker.send(args);
     
      } else {
        const worker = new Worker(getWorkerPath(path), options);
        worker.on('message', (msg) => {
          resolve(msg)
          worker.terminate()
        });
        worker.on('error', (err) => {
          reject(err)
        });
        worker.postMessage(args);
      }
     
  })
}


export function removeTypeFromFunction(tsFunction: string) {
  if (!tsFunction) {
    return ''
  }
  // 使用正则表达式匹配并替换函数参数的类型注解
  const jsFunction = tsFunction.replace(/:\s*\w+(\.\w+)?(\[\])?(?:\s*\|\s*\w+(\.\w+)?(\[\])?)*\s*(?=(,|\)))/g, '');

  return jsFunction;
}